package cn.oi.klittle.era.utils

import android.content.Context
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import cn.oi.klittle.era.base.KBaseApplication
import cn.oi.klittle.era.socket.KIpPort
import java.util.*

//                    fixme uuid基本使用
//                    var mostSigBits:Long=0
//                    var leastSigBits:Long=0
//                    //生成一个UUID;生成后的格式为：8-4-4-4-12 共32位;如：d9bc5194-431d-49ed-b3b6-4a1b72005934
//                    var uuid=UUID(mostSigBits,leastSigBits)//uuid 就等价于 uuid.toString()
//
//                    //生成一个指定的uuid,格式必须是 8-4-4-4-12;生成的uuid就是参数里的字符串(fixme 即字符串转UUID)
//                    var uuid2=UUID.fromString("d9bc5194-431d-49ed-b3b6-4a1b72005934")

/**
 * fixme 获取设备唯一标识。
 * uuid的格式是：8-4-4-4-12 共32个字符，加上中间的横杆就是36位。如：d9bc5194-431d-49ed-b3b6-4a1b72005934
 * var uuid=UUID.randomUUID()//生成一个随机的uuid
 * var uuid2=UUID.fromString("d9bc5194-431d-49ed-b3b6-4a1b72005934")//生成一个指定的uuid,格式必须是 8-4-4-4-12
 * 其中 uuid 就等价于 uuid.toString()
 */
object KUniQueUtils {

    private fun getContext(): Context {
        return KBaseApplication.getInstance().applicationContext
    }

    //fixme 获取mac地址
    ////通过wifi（与wifi是否开启没有关系，亲测能够获取） 获取mac地址[物理地址，不会变。理论上是不变，因为是出厂时被厂家烧在网卡上的。但不能保证绝对。]
    fun getMacAddress(): String {
        return KIpPort.getMacAddress()
    }

    /**
     * fixme UUID+设备号序列号 唯一识别码（不可变）;注意，这个需要读取手机状态的权限哦(不然异常)。
     * 返回结果如：00000000-11d5-776d-fcc1-ea550033c587 32个字符，加上中间的-就是36个。
     */
    fun getDeviceUuid(): String? {
        //需要读取手机状态的权限。这里仅仅做判断，不主动做动态申请。
        if (KPermissionUtils.requestPermissionsReadPhoneState(null)) {
            //TelephonyManager 这一步就需要权限。deviceId或androidId都需要权限。
            var tm = getContext().getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager;
            //var deviceId: String = tm?.getDeviceId();//fixme 该方法已经弃用。会报错。
            //var tmSerial = "" + tm.getSimSerialNumber();
            var deviceId: String = "tm?.getDeviceId()";
            var tmSerial = "" + "tm.getSimSerialNumber()";
            var androidId = android.provider.Settings.Secure.getString(
                    getContext().getContentResolver(), android.provider.Settings.Secure.ANDROID_ID);
            val deviceUuid = UUID(androidId.hashCode().toLong(), deviceId.hashCode().toLong() shl 32 or tmSerial.hashCode().toLong())
            return deviceUuid.toString()
        }
        return null//没有权限，返回为空。自己手动去申请。
    }

    ///获取唯一标识；将UUID转成Int数字类型。
    ///即：32位转10位数字,如：ffffffff-ab23-9c0f-ffff-ffff9363c4ff -> 1122037350
    fun getUniquePsuedoIDWithInt(context: Context): String {
        var uuid= getUniquePsuedoID(context);
        var PsuedoID: Int = uuid.toString().hashCode()
        //KLoggerUtils.e("PsuedoID:\t"+PsuedoID)
        //可能会为负数，如果为负数，则变成正数。
        PsuedoID = if (PsuedoID < 0) -PsuedoID else PsuedoID
        return PsuedoID.toString();
        //return java.lang.Long.valueOf(PsuedoID.toString()).toString();
    }

    //不需要任何权限。最保险。
    //获得独一无二的Psuedo ID【如：ffffffff-80ac-a8f1-ffff-ffff8e4712be 一般为32位，加上中间的-就是36位。】,等价于设备号ID【设备唯一标识】
    //如：00000000-2246-54a5-0000-000078c4332f
    //如：ffffffff-ab23-9c0f-ffff-ffff9363c4ff
    //fixme 注意：和签名有关，相同签名，获取ANDROID_ID相同；不同签名，获取ANDROID_ID不同。(亲测)
    fun getUniquePsuedoID(context: Context): String {
        //fixme 以下获取方式规定好了，就不要再随意变动了。原则上不能再变动。切记！
        //主板+品牌+型号+设置参数+ID；sdm845/Xiaomi/MI 8/dipper/QKQ1.190828.002
        var ANDROID_ID = Build.BOARD + "/" + Build.BRAND + "/" + Build.MODEL + "/" + Build.DEVICE + "/" + Build.ID + "/";
        //  fixme Build.ID;具有唯一性；不同签名的应用获取的Build.ID也是相同的。
        try {
            //b4e67c28b9c2da02 测试发现，获取ANDROID_ID不需要用户权限。(亲测)
            //fixme 主要在 Android 8 以上，不同签名的应用获取到的 Android ID 不同（亲测）。
            //fixme 和签名有关，相同签名，获取ANDROID_ID相同；不同签名，获取ANDROID_ID不同。(亲测)
            ANDROID_ID += Settings.System.getString(
                    context.contentResolver, Settings.Secure.ANDROID_ID);
        } catch (e: java.lang.Exception) {
            //KLoggerUtils.e("ANDROID_ID 获取异常：" + KCatchException.getExceptionMsg(e))
        }
        //KLoggerUtils.e("ANDROID_ID:" + ANDROID_ID)//sdm845/Xiaomi/MI 8/dipper/QKQ1.190828.002
        // var m_szDevIDShort = "Psuedo ID:" +
        //         Build.BOARD.length % 10 + Build.BRAND.length % 10 +
        //         Build.CPU_ABI.length % 10 + Build.DEVICE.length % 10 +
        //         Build.DISPLAY.length % 10 + Build.HOST.length % 10 +
        //         Build.ID.length % 10 + Build.MANUFACTURER.length % 10 +
        //         Build.MODEL.length % 10 + Build.PRODUCT.length % 10 +
        //         Build.TAGS.length % 10 + Build.TYPE.length % 10 +
        //         Build.USER.length % 10
        var m_szDevIDShort = "Psuedo ID:" +
                Build.BOARD.length % 10 + Build.BRAND.length % 10 +
                Build.ID.length % 10 + Build.DEVICE.length % 10 +
                Build.DISPLAY.length % 10 + Build.HOST.length % 10 +
                Build.ID.length % 10 + Build.MANUFACTURER.length % 10 +
                Build.MODEL.length % 10 + Build.PRODUCT.length % 10 +
                Build.TAGS.length % 10 + Build.TYPE.length % 10 +
                Build.USER.length % 10//fixme 使用硬件信息拼凑出来的13位号码;具有唯一性（亲测）
        //KLoggerUtils.e("m_szDevIDShort:"+m_szDevIDShort)//Psuedo ID:6696595646247
        m_szDevIDShort += ANDROID_ID;
        var serial: String? = ANDROID_ID
        //try {
        //    //serial = Build::class.java.getField("SERIAL").get(null).toString()//测试发现，这个基本都能获取成功。
        //    // if (Build.VERSION.SDK_INT >= 26) {
        //    //     //Build.getSerial() 需要手机状态读取权限。
        //    //     //fixme 即使获取了读取手机用户的权限，andrid 10 也会返回：unknown;也就是说SERIAL序列号靠不住了。
        //    //     serial = Build.getSerial();
        //    // } else {
        //    //     serial = Build.SERIAL;
        //    // }
        //    //KLoggerUtils.e("serial:"+serial)//unknown
        //    //m_szDevIDShort:	Psuedo ID:7496666461946 13位
        //    //serial:	810717032865
        //    //KLoggerUtils.e("m_szDevIDShort:\t"+m_szDevIDShort,true)
        //    //KLoggerUtils.e("serial:\t"+serial,true)
        //    //API>=9 使用serial号
        //    serial += ANDROID_ID;
        //    return UUID(m_szDevIDShort.hashCode().toLong(), serial.hashCode().toLong()).toString()
        //} catch (exception: Exception) {
        //    //KLoggerUtils.e("反射SERIAL 获取异常：" + KCatchException.getExceptionMsg(exception))
        //    //serial需要一个初始化
        //    serial = "SERIAL" + ANDROID_ID // 随便一个初始化
        //}
        return UUID(m_szDevIDShort.hashCode().toLong(), serial!!.hashCode().toLong()).toString()
    }

    var letteres = mutableListOf<String>("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z")

    //生成随机字符【格式(包含数字和小写字符)：7gc0y3】
    //确保每次生成都尽可能不一样（随机个数count越大越好。）
    fun getSecurityRandom(count: Int): String {
        if (count > 0) {
            var code = ""
            // 生成正随机数
            for (i in 0 until count) {
                // 以时间为种子(每次循环都重新实例化一个Random，增大随机概率。)
                var rand = Random((Math.random() * 100000000).toLong() + System.currentTimeMillis())
                var c = Math.abs(rand.nextInt() % 36).toString()
                c = letteres.get(c.toInt())
                code = code + c
            }
            return code
        } else {
            KLoggerUtils.e("TEST", "随机个数少于0")
            return "0"
        }
    }

    /**
     * 将32位的字符串转UUID格式：8-4-4-4-12 共32个字符；加上中间的斜杠共36个字符。
     * @param str 必须是32位长度的字符串
     *
     */
    fun toUUID(str: String): UUID? {
        try {
            str?.let {
                if (it.length == 32) {
                    //fixme 必须是32位长度
                    //substring(开始下标，结束下标)；截取的结果是包含开始下标；但不包含结束下标。
                    var one_8 = it.substring(0, 8)
                    var two_4 = it.substring(8, 12)
                    var three_4 = it.substring(12, 16)
                    var four_4 = it.substring(16, 20)
                    var five_12 = it.substring(20, 32)
                    return UUID.fromString(one_8 + "-" + two_4 + "-" + three_4 + "-" + four_4 + "-" + five_12)
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
            KLoggerUtils.e("32位字符串转UUID格式异常:\t" + e.message, isLogEnable = true)
        }
        return null
    }

    ///获取设备硬件信息
    fun getUniquePsuedoStr(): String {
        return "BOARD:" + Build.BOARD + "\n" +
                "BRAND:" + Build.BRAND + "\n" +
                "CPU_ABI:" + Build.CPU_ABI + "\n" +
                "DEVICE:" + Build.DEVICE + "\n" +
                "DISPLAY:" + Build.DISPLAY + "\n" +
                "HOST:" + Build.HOST + "\n" +
                "ID:" + Build.ID + "\n" +
                "MANUFACTURER:" + Build.MANUFACTURER + "\n" +
                "MODEL:" + Build.MODEL + "\n" +
                "PRODUCT:" + Build.PRODUCT + "\n" +
                "TAGS:" + Build.TAGS + "\n" +
                "TYPE:" + Build.TYPE + "\n" +
                "USER:" + Build.USER;
//        主板 BOARD:sdm845
//        品牌 BRAND:Xiaomi
//        处理器 CPU_ABI:arm64-v8a
//        设备参数 DEVICE:dipper
//        显示屏参数 DISPLAY:QKQ1.190828.002 test-keys
//        HOST:c4-miui-ota-bd48.bj
//        ID:QKQ1.190828.002
//        MANUFACTURER:Xiaomi
//        MODEL:MI 8
//        PRODUCT:dipper
//        TAGS:release-keys
//        TYPE:user
//        USER:builder
    }

    ///设备信息
    fun getDeviceInfo(): String? {
        val sb = StringBuffer()
        sb.append("""
    主板： ${Build.BOARD}
    
    """.trimIndent())
        sb.append("""
    系统启动程序版本号： ${Build.BOOTLOADER}
    
    """.trimIndent())
        sb.append("""
    系统定制商：${Build.BRAND}
    
    """.trimIndent())
        sb.append("""
    cpu指令集： ${Build.CPU_ABI}
    
    """.trimIndent())
        sb.append("""
    cpu指令集2 ${Build.CPU_ABI2}
    
    """.trimIndent())
        sb.append("""
    设置参数： ${Build.DEVICE}
    
    """.trimIndent())
        sb.append("""
    显示屏参数：${Build.DISPLAY}
    
    """.trimIndent())
        sb.append("""
    无线电固件版本：${Build.getRadioVersion()}
    
    """.trimIndent())
        sb.append("""
    硬件识别码：${Build.FINGERPRINT}
    
    """.trimIndent())
        sb.append("""
    硬件名称：${Build.HARDWARE}
    
    """.trimIndent())
        sb.append("""
    HOST: ${Build.HOST}
    
    """.trimIndent())
        sb.append("""
    修订版本列表：${Build.ID}
    
    """.trimIndent())
        sb.append("""
    硬件制造商：${Build.MANUFACTURER}
    
    """.trimIndent())
        sb.append("""
    版本：${Build.MODEL}
    
    """.trimIndent())
        sb.append("""
    硬件序列号：${Build.SERIAL}
    
    """.trimIndent())
        sb.append("""
    手机制造商：${Build.PRODUCT}
    
    """.trimIndent())
        sb.append("""
    描述Build的标签：${Build.TAGS}
    
    """.trimIndent())
        sb.append("""
    TIME: ${Build.TIME}
    
    """.trimIndent())
        sb.append("""
    builder类型：${Build.TYPE}
    
    """.trimIndent())
        sb.append("""
    USER: ${Build.USER}
    
    """.trimIndent())
        return sb.toString()
    }
}